package cn.tedu.charging.device.dao.repository.impl;

import cn.tedu.charging.device.dao.repository.StationCacheRepository;
import cn.tedu.charging.device.pojo.po.StationCanalPO;
import cn.tedu.charging.device.pojo.po.StationPO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository("GeoAndGeo")
        public class StationCacheGeoAndGeoRepositoryImpl implements StationCacheRepository {

    private static final Logger log = LoggerFactory.getLogger(StationCacheGeoAndGeoRepositoryImpl.class);
    @Autowired
    private RedisTemplate redisTemplate;

    private static final String STATIONS_KEY = "stations";

    @Override
    public void saveAllStations(List<StationPO> stations) {
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        Map<StationPO,Point> map = new HashMap<>();
        stations.forEach(stationPO -> {
            //Point 是Spring-data-redis封装的一个对象 表示位置 一个点 入参是经纬度
            Point point = new Point(stationPO.getStationLng().doubleValue(),
                    stationPO.getStationLat().doubleValue());
            //一个一个的保存 不推荐
            //geoOperations.add("stations",point,stationPO);
            map.put(stationPO,point);
        });
        //批量保存，
        //在操作数据库的时候，如果要保存多条数据，那么就可以使用批量操作，
        // 比如批量保存，批量删除，批量修改等。
        //封装的 GEOADD 这个命令
        geoOperations.add(STATIONS_KEY,map);
        //BoundGeoOperations stations1 = redisTemplate.boundGeoOps("stations");
        //GEOADD key longitude latitude member
    }

    @Override
    public List<StationPO> search(Double lng, Double lat, Integer distance) {
        GeoOperations geoOperations = redisTemplate.opsForGeo();

        //通过经纬度 创建一个 Point 对象
        Point point = new Point(lng,lat);
        //通过距离 设置 圆的半径 同时设置距离的单位 KILOMETERS
        //附近的充电站，附近的酒店 都是距离单位是 KILOMETERS
        //步行导航 附近的共享单车，共享充电宝 距离单位应该是 米
        Distance queryDistance = new Distance(distance, Metrics.KILOMETERS);
        //通过 点 和 半径 画个圆
        Circle circle = new Circle(point,queryDistance);
        GeoResults<RedisGeoCommands.GeoLocation<StationPO>> radius =
                geoOperations.radius(STATIONS_KEY, circle);
        List<StationPO> stationPOS = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<StationPO>> result : radius) {
            //GeoResult 里的具体的数据 用 content 来表示
            RedisGeoCommands.GeoLocation<StationPO> content = result.getContent();
            Distance resultDistance = result.getDistance();
            log.debug("距离:{}",resultDistance);
            //name 表示的是 GEOADD  是 member StationPO
            StationPO stationPO = content.getName();
            stationPOS.add(stationPO);
        }
        return stationPOS;
    }

    @Override
    public void insert(StationCanalPO stationCanalPO) {
        //todo
    }

    @Override
    public void update(StationCanalPO before, StationCanalPO after) {
        //todo
    }

    @Override
    public void delete(StationCanalPO stationCanalPO) {
        //todo
    }
}
